home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / xgopher.1.3 / panel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-25  |  26.5 KB  |  1,137 lines

  1. /* panel.c
  2.    make and handle callbacks for the main Xgopher panel */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <X11/Intrinsic.h>
  22. #include <X11/StringDefs.h>
  23. #include <X11/cursorfont.h>
  24. #include <X11/Xaw/Box.h>
  25. #include <X11/Xaw/Command.h>
  26. #include <X11/Xaw/Form.h>
  27. #include <X11/Xaw/Label.h>
  28. #include <X11/Xaw/List.h>
  29. #include <X11/Xaw/Paned.h>
  30. #include <X11/Xaw/Scrollbar.h>
  31. #include <X11/Xaw/Simple.h>
  32. #include <X11/Xaw/Viewport.h>
  33. #include <X11/Xaw/SimpleMenu.h>
  34. #include <X11/Xaw/MenuButton.h>
  35. #include <X11/Xaw/SmeBSB.h>
  36.  
  37.  
  38. #include "gopher.h"
  39. #include "panel.h"
  40. #include "compatR4.h"
  41. #include "item.h"
  42. #include "itemList.h"
  43. #include "dirList.h"
  44. #include "dir.h"
  45. #include "markList.h"
  46. #include "misc.h"
  47. #include "util.h"
  48. #include "single.h"
  49. #include "options.h"
  50. #include "help.h"
  51. #include "bkmkfile.h"
  52. #include "appres.h"
  53. #include "xglobals.h"
  54. #include "globals.h"
  55.  
  56.  
  57. static Widget    dirLabel, dirList,
  58.         markLabel, markList,
  59.         unmarkButton, infoButton,
  60.         markButton,
  61.         upButton, fetchButton,
  62.         copyButton, saveButton, loadButton, unmarkAllButton,
  63.         statusLabel,
  64.         gopherPanel,
  65.         topLevel;
  66.  
  67. static char    *emptyList[] = {"<none>", NULL};
  68. static    int    selectedDir = XAW_LIST_NONE, selectedMark = XAW_LIST_NONE;
  69.  
  70.  
  71. static void     fetchProc();
  72. static void    restartProc();
  73.  
  74.  
  75.  
  76. #define STATE_OF(w, button, condition) \
  77.     if ((condition)) {              \
  78.         if (!(currentState & (button))) {      \
  79.         XtSetValues((w), &sensitive, 1);      \
  80.         currentState |= (button);      \
  81.         }                      \
  82.     } else {                  \
  83.         if (currentState & button) {      \
  84.         XtSetValues((w), &insensitive, 1);  \
  85.         currentState &= ~(button);      \
  86.         }                      \
  87.     }
  88.  
  89. #define ANYTHING_SELECTED    ((selectedDir  != XAW_LIST_NONE) || \
  90.                  (selectedMark != XAW_LIST_NONE))
  91.  
  92. #define MARK_SELECTED        (selectedMark != XAW_LIST_NONE)
  93. #define NONMARK_SELECTED    (selectedDir != XAW_LIST_NONE)
  94.  
  95. static buttonSet    currentState = BS_all | LS_items;
  96.  
  97. static Arg        infoItemLabelArg = {"label", (XtArgVal) NULL},
  98.             infoDirLabelArg  = {"label", (XtArgVal) NULL},
  99.             markItemLabelArg = {"label", (XtArgVal) NULL},
  100.             markDirLabelArg  = {"label", (XtArgVal) NULL};
  101.  
  102. void
  103. checkButtonState(which)
  104. buttonSet    which;
  105. {
  106.     static Arg
  107.         sensitive     = {"sensitive", TRUE},
  108.         insensitive     = {"sensitive", FALSE};
  109.  
  110.     if (which & BS_fetch) {
  111.         STATE_OF(fetchButton, BS_fetch, ANYTHING_SELECTED);
  112.     }
  113.  
  114.     if (which & BS_previous) {
  115.         STATE_OF(upButton, BS_previous,
  116.             (previousDir(getCurrentDir()) != NULL));
  117.     }
  118.  
  119.     if (which & BS_unmark) {
  120.         STATE_OF(unmarkButton, BS_unmark,
  121.             MARK_SELECTED);
  122.     }
  123.  
  124.  
  125.     /* condition could include test to see if file is copy-able */
  126.  
  127.     if (which & BS_copy) {
  128.         if (copyButton != NULL) {
  129.             STATE_OF(copyButton, BS_copy, (ANYTHING_SELECTED));
  130.         }
  131.     }
  132.  
  133.  
  134.     /* the sensitivity of the mark list tracks the state of unmarkAll */
  135.  
  136.     if (which & BS_unmarkAll) {
  137.         if (markListLength() != 0) {
  138.             if (!(currentState & BS_unmarkAll)) {
  139.             XtSetValues(unmarkAllButton, &sensitive, 1);
  140.             XtSetValues(markList, &sensitive, 1);
  141.             currentState |= (BS_unmarkAll);
  142.             }
  143.         } else {
  144.             if (currentState & BS_unmarkAll) {
  145.             XtSetValues(unmarkAllButton, &insensitive, 1);
  146.             XtSetValues(markList, &insensitive, 1);
  147.             currentState &= ~(BS_unmarkAll);
  148.             }
  149.         }
  150.     }
  151.  
  152.  
  153.     if (which & BS_loadMarks) {
  154.         STATE_OF(loadButton, BS_loadMarks,
  155.             (appResources->bookmarkFile != NULL &&
  156.              *(appResources->bookmarkFile) != '\0'));
  157.     }
  158.  
  159.  
  160.     if (which & BS_saveMarks) {
  161.         if (saveButton != NULL) {
  162.             STATE_OF(saveButton, BS_saveMarks,
  163.                 ((appResources->allowBookmarkSave) &&
  164.                  (appResources->bookmarkFile != NULL) &&
  165.                  *(appResources->bookmarkFile) != '\0' &&
  166.                  (markListLength() != 0)));
  167.         }
  168.     }
  169.  
  170.  
  171.     if (which & BS_info) {
  172.  
  173.         if (ANYTHING_SELECTED  ||  (getCurrentDir() != NULL)) {
  174.             if (!(currentState & BS_info)) {
  175.             XtSetValues(infoButton, &sensitive, 1);
  176.             currentState |= (BS_info);
  177.             }
  178.             if (ANYTHING_SELECTED) {
  179.             if (!(currentState & LS_infoItem)) {
  180.                 XtSetValues (infoButton, &infoItemLabelArg, 1);
  181.                 currentState |= (LS_infoItem);
  182.             }
  183.             } else {
  184.             if (currentState & LS_infoItem) {
  185.                 XtSetValues (infoButton, &infoDirLabelArg, 1);
  186.                 currentState &= ~(LS_infoItem);
  187.             }
  188.             }
  189.         } else {
  190.             if (currentState & BS_info) {
  191.             XtSetValues(infoButton, &insensitive, 1);
  192.             currentState &= ~(BS_info);
  193.             }
  194.         }
  195.     }
  196.  
  197.  
  198.     if (which & BS_mark) {
  199.  
  200.         if (NONMARK_SELECTED || (getCurrentDir() != NULL)) {
  201.             if (!(currentState & (BS_mark))) {
  202.             XtSetValues(markButton, &sensitive, 1);
  203.             currentState |= (BS_mark);
  204.             }
  205.             if (NONMARK_SELECTED) {
  206.             if (!(currentState & LS_markItem)) {
  207.                 XtSetValues (markButton, &markItemLabelArg, 1);
  208.                 currentState |= (LS_markItem);
  209.             }
  210.             } else {
  211.             if (currentState & LS_markItem) {
  212.                 XtSetValues (markButton, &markDirLabelArg, 1);
  213.                 currentState &= ~(LS_markItem);
  214.             }
  215.             }
  216.         } else {
  217.             if (currentState & BS_mark) {
  218.             XtSetValues(markButton, &insensitive, 1);
  219.             currentState &= ~(BS_mark);
  220.             }
  221.         }
  222.     }
  223. }
  224.  
  225.  
  226. /* unselectAllProc
  227.    unselect everything in the directory or bookmark lists. */
  228.  
  229. void
  230. unselectAllProc(w, client_data, call_data)
  231. Widget        w;
  232. XtPointer    client_data, call_data;
  233. {
  234.     XawListUnhighlight(dirList);
  235.     selectedDir = XAW_LIST_NONE;
  236.  
  237.     XawListUnhighlight(markList);
  238.     selectedMark = XAW_LIST_NONE;
  239.  
  240.     checkButtonState(BS_changeSelected);
  241. }
  242.  
  243.  
  244. /* dirSelectProc
  245.    callback for a directory selection */
  246.  
  247. void
  248. dirSelectProc(w, client_data, call_data)
  249. Widget        w;
  250. XtPointer    client_data, call_data;
  251. {
  252.     XawListReturnStruct    *val = (XawListReturnStruct *) call_data;
  253.     gopherItemP        gi;
  254.  
  255.     if (selectedMark != XAW_LIST_NONE) {
  256.         XawListUnhighlight(markList);
  257.         selectedMark = XAW_LIST_NONE;
  258.     }
  259.  
  260.     if (appResources->doubleClick  &&  selectedDir == val->list_index) {
  261.         fetchProc(fetchButton, FALSE, NULL);
  262.     } else {
  263.         selectedDir = val->list_index;
  264.         checkButtonState(BS_changeSelected);
  265.     }
  266.  
  267.     return;
  268. }
  269.  
  270.  
  271. /* markSelectProc
  272.    callback for a bookmark selection */
  273.  
  274. void
  275. markSelectProc(w, client_data, call_data)
  276. Widget        w;
  277. XtPointer    client_data, call_data;
  278. {
  279.     XawListReturnStruct    *val = (XawListReturnStruct *) call_data;
  280.     gopherItemP        gi;
  281.  
  282.     if (selectedDir != XAW_LIST_NONE) {
  283.         XawListUnhighlight(dirList);
  284.         selectedDir = XAW_LIST_NONE;
  285.     }
  286.  
  287.     if (appResources->doubleClick  &&  selectedMark == val->list_index) {
  288.         fetchProc(fetchButton, FALSE, NULL);
  289.     } else {
  290.         selectedMark = val->list_index;
  291.         checkButtonState(BS_changeSelected);
  292.     }
  293.  
  294.     return;
  295. }
  296.  
  297.  
  298. /* fetchProc
  299.    callback to go to a bookmark or directory item */
  300.  
  301. static void
  302. fetchProc(w, client_data, call_data)
  303. Widget        w;
  304. XtPointer    client_data, call_data;
  305. {
  306.     gopherItemP    gi;
  307.     BOOLEAN        pushed = (BOOLEAN) client_data;
  308.     BOOLEAN        copy   = (w != fetchButton);
  309.  
  310.     if (selectedDir != XAW_LIST_NONE) {
  311.         gi = getItemN(getDirContents(getCurrentDir()), selectedDir);
  312.         selectedDir = XAW_LIST_NONE;
  313.         XawListUnhighlight(dirList);
  314.         if (gi != NULL) {
  315.             if (!pushed) XtCallActionProc(fetchButton,
  316.                         "set", NULL, NULL, 0);
  317.             copy ? copyItemToFile(gi) : processItem(gi);
  318.             if (!pushed) XtCallActionProc(fetchButton,
  319.                         "unset", NULL, NULL, 0);
  320.             checkButtonState(BS_changeSelected | BS_previous);
  321.         }
  322.     } else if (selectedMark != XAW_LIST_NONE) {
  323.         gi = getMarkN(selectedMark);
  324.         selectedMark = XAW_LIST_NONE;
  325.         XawListUnhighlight(markList);
  326.         if (gi != NULL) {
  327.             if (!pushed) XtCallActionProc(fetchButton,
  328.                         "set", NULL, NULL, 0);
  329.             copy ? copyItemToFile(gi) : processItem(gi);
  330.             if (!pushed) XtCallActionProc(fetchButton,
  331.                         "unset", NULL, NULL, 0);
  332.             checkButtonState(BS_changeSelected | BS_previous);
  333.         }
  334.     } else {
  335.         /* nothing selected */
  336.  
  337.         showError( copy ?
  338.             "Something must be selected before it can be copied"
  339.         :
  340.             "Something must be selected before it can be fetched");
  341.     }
  342. }
  343.  
  344.  
  345. /* whichItemSelected
  346.    return the item which is highlighted, or null if none is selected. */
  347.  
  348. gopherItemP
  349. whichItemSelected()
  350. {
  351.     gopherItemP    gi;
  352.  
  353.     if (selectedDir != XAW_LIST_NONE) {
  354.         gi = getItemN(getDirContents(getCurrentDir()), selectedDir);
  355.  
  356.     } else if (selectedMark != XAW_LIST_NONE) {
  357.         gi = getMarkN(selectedMark);
  358.     
  359.     } else {
  360.         gi = NULL;
  361.     }
  362.  
  363.     return gi;
  364. }
  365.  
  366.  
  367. /* infoProc
  368.    callback to get the raw gopher info or gopher+ info for an item
  369.    and display it */
  370.  
  371. void
  372. infoProc(w, client_data, call_data)
  373. Widget        w;
  374. XtPointer    client_data, call_data;
  375. {
  376.     gopherItemP    gi;
  377.     gopherDirP    gd;
  378.  
  379.     if (selectedDir != XAW_LIST_NONE) {
  380.         gi = getItemN(getDirContents(getCurrentDir()), selectedDir);
  381.  
  382.     } else if (selectedMark != XAW_LIST_NONE) {
  383.         gi = getMarkN(selectedMark);
  384.     
  385.     } else {
  386.         if ((gd = getCurrentDir()) != NULL) {
  387.             gi = gd->selectorItem;
  388.         } else {
  389.             gi = NULL;
  390.         }
  391.     }
  392.  
  393.     showItemInfo(gi);
  394. }
  395.  
  396.  
  397. /* quitProc
  398.    exit callback.  The client_data provided to the callback
  399.    determines if the callback was called by the quit button (action) or
  400.    the restart button (action).  TRUE for QUIT, FALSE for RESTART. */
  401.  
  402. void
  403. quitProc(w, client_data, call_data)
  404. Widget        w;
  405. XtPointer    client_data, call_data;
  406. {
  407.     BOOLEAN    reallyQuit = (BOOLEAN) client_data;
  408.  
  409.     reallyQuit  = reallyQuit ^ appResources->swapRestartAndQuit;
  410.     
  411.     if (reallyQuit) {
  412.  
  413.         if (appResources->allowBookmarkSave) bkmkSave();
  414.  
  415.         /* let each item class clean up anything it wants to */
  416.  
  417.         doneItemClasses();
  418.  
  419.         closeGUIandQuit(0);
  420.     } else {
  421.         restartProc(w, client_data, call_data);
  422.     }
  423. }
  424.  
  425.  
  426. /* helpProc
  427.    help callback. */
  428.  
  429. void
  430. helpProc(w, client_data, call_data)
  431. Widget        w;
  432. XtPointer    client_data, call_data;
  433. {
  434.  
  435.     showHelp("xgopher help");
  436. }
  437.  
  438.  
  439. /* markLoadProc
  440.    load bookmarks callback. */
  441.  
  442. void
  443. markLoadProc(w, client_data, call_data)
  444. Widget        w;
  445. XtPointer    client_data, call_data;
  446. {
  447.  
  448.     selectedMark = XAW_LIST_NONE;
  449.     bkmkLoad();
  450.     displayBookmarks();
  451.     checkButtonState(BS_all);
  452. }
  453.  
  454.  
  455. /* markSaveProc
  456.    save bookmarks callback. */
  457.  
  458. void
  459. markSaveProc(w, client_data, call_data)
  460. Widget        w;
  461. XtPointer    client_data, call_data;
  462. {
  463.  
  464.     if (appResources->allowBookmarkSave) bkmkSave();
  465. }
  466.  
  467.  
  468. /* optionsProc
  469.    options callback. */
  470.  
  471. void
  472. optionsProc(w, client_data, call_data)
  473. Widget        w;
  474. XtPointer    client_data, call_data;
  475. {
  476.  
  477.     showOptionsPanel();
  478. }
  479.  
  480.  
  481. /* oneItemProc
  482.    single custom gopher item callback. */
  483.  
  484. void
  485. oneItemProc(w, client_data, call_data)
  486. Widget        w;
  487. XtPointer    client_data, call_data;
  488. {
  489.     showSinglePanel();
  490. }
  491.  
  492.  
  493. /* versionProc
  494.    version callback. */
  495.  
  496. void
  497. versionProc(w, client_data, call_data)
  498. Widget        w;
  499. XtPointer    client_data, call_data;
  500. {
  501.  
  502.     displayVersionPanel(topLevel);
  503. }
  504.  
  505.  
  506. /* markProc
  507.    callback to set a bookmark at the current directory */
  508.  
  509. void
  510. markProc(w, client_data, call_data)
  511. Widget        w;
  512. XtPointer    client_data, call_data;
  513. {
  514.     gopherDirP    gd = getCurrentDir();
  515.     gopherItemP    gi;
  516.  
  517.     if (selectedDir != XAW_LIST_NONE) {
  518.         gi = copyItem( getItemN(getDirContents(gd),
  519.                     selectedDir));
  520.     } else if (gd != NULL) {
  521.         gi = copyItem(gd->selectorItem);
  522.     } else {
  523.         gi = NULL;
  524.     }
  525.  
  526.     if (gi != NULL) {
  527.         markItem(gi);
  528.         selectedMark = XAW_LIST_NONE;
  529.         displayBookmarks();
  530.         checkButtonState(BS_unmark | BS_unmarkAll | BS_saveMarks);
  531.     }
  532. }
  533.  
  534.  
  535. /* unmarkProc
  536.    callback to delete a bookmark */
  537.  
  538. void
  539. unmarkProc(w, client_data, call_data)
  540. Widget        w;
  541. XtPointer    client_data, call_data;
  542. {
  543.     XawListReturnStruct    *val;
  544.  
  545.     val = XawListShowCurrent(markList);
  546.     if (val->list_index != XAW_LIST_NONE) {
  547.         selectedDir = selectedMark = XAW_LIST_NONE;
  548.         unmarkItemN(val->list_index);
  549.         displayBookmarks();
  550.         checkButtonState(BS_unmark | BS_unmarkAll |
  551.                 BS_saveMarks | BS_changeSelected);
  552.     }
  553. }
  554.  
  555.  
  556. /* unmarkAllProc
  557.    callback to delete all bookmarks */
  558.  
  559. void
  560. unmarkAllProc(w, client_data, call_data)
  561. Widget        w;
  562. XtPointer    client_data, call_data;
  563. {
  564.     selectedMark = XAW_LIST_NONE;
  565.     unmarkAllItems();
  566.     displayBookmarks();
  567.     checkButtonState(BS_unmark | BS_unmarkAll |
  568.             BS_saveMarks | BS_changeSelected);
  569. }
  570.  
  571.  
  572. /* upProc
  573.    callback to go up a level */
  574.  
  575. void
  576. upProc(w, client_data, call_data)
  577. Widget        w;
  578. XtPointer    client_data, call_data;
  579. {
  580.     selectedDir = selectedMark = XAW_LIST_NONE;
  581.     XawListUnhighlight(markList);
  582.     clearDirWhenOld(previousDir(getCurrentDir()));
  583.     popCurrentDir();
  584.     displayCurrent();
  585.     checkButtonState(BS_changeSelected | BS_previous);
  586. }
  587.  
  588.  
  589. /* restartProc
  590.    restart callback. */
  591.  
  592. static void
  593. restartProc(w, client_data, call_data)
  594. Widget        w;
  595. XtPointer    client_data, call_data;
  596. {
  597.     /* for restart:
  598.        . undo any current selections
  599.        . save and discard bookmarks
  600.        . remove options panel
  601.        . remove enter gopher item panel
  602.        . reset options that the user may have changed on the option panel
  603.        . restart class-dependent things:
  604.          - clear directory stack
  605.          - get rid of any displayed text windows,
  606.          - get rid of any temp files
  607.          - remove name server panel
  608.          - kill sound being played
  609.          - remove index panel
  610.        . process initial gopher item
  611.        X (can't get rid of telnet/tn3270/??? since we don't
  612.          really have a handle on them (e.g., PID)
  613.     */
  614.  
  615.     char        errorString[MESSAGE_STRING_LEN];
  616.  
  617.     LOG (logFP, "Restart Xgopher\n");
  618.  
  619.     unselectAllProc(NULL, NULL, NULL);
  620.  
  621.     if (appResources->allowBookmarkSave) bkmkSave();
  622.     unmarkAllProc(NULL, NULL, NULL);
  623.     
  624.     endSinglePanel();
  625.     removeOptionsPanel();
  626.  
  627.     if (appResources->resetOptions) {
  628.         restoreChangableResources(appResources);
  629.     }
  630.  
  631.     /* remove old directories, text, sound, index, cso panels */
  632.  
  633.     restartItemClasses();
  634.  
  635.     /* ready to make a clean slate and start over */
  636.  
  637.     displayCurrent();
  638.     checkButtonState(BS_all);
  639.  
  640.     doMainItem();
  641.  
  642. }
  643.  
  644.  
  645. /* changeDirLabel
  646.    change the directory list label */
  647.  
  648. void
  649. changeDirLabel(newLabel)
  650. char    *newLabel;
  651. {
  652.     Arg        args[2];
  653.     Cardinal    n = 0;
  654.     
  655.     XtSetArg(args[n], XtNlabel, (String) newLabel);  n++;
  656.     XtSetValues(dirLabel, args, n);
  657. }
  658.  
  659.  
  660. /* changeStatusLabel
  661.    change the status label */
  662.  
  663. void
  664. changeStatusLabel(newLabel, statType)
  665. char    *newLabel;
  666. int    statType;
  667. {
  668.     Arg        args[10];
  669.     Cardinal    n = 0;
  670.     Display        *dpy;
  671.     static BOOLEAN  waitDefined  = FALSE;
  672.     static        Window    waitWindow;
  673.  
  674.     dpy = XtDisplay(gopherPanel);
  675.     
  676.  
  677.     /* Change cursors to show a long wait maybe */
  678.  
  679.     if (! waitDefined) {
  680.         /* following is from the FAQ file in comp.windows.x */
  681.  
  682.         unsigned long valuemask;
  683.         XSetWindowAttributes attributes;
  684.  
  685.         waitDefined = TRUE;
  686.  
  687.         /* Ignore device events while the busy cursor is displayed. */
  688.  
  689.         valuemask = CWDontPropagate | CWCursor;
  690.         attributes.do_not_propagate_mask =
  691.             (KeyPressMask | KeyReleaseMask |
  692.             ButtonPressMask | ButtonReleaseMask |
  693.             PointerMotionMask);
  694.         attributes.cursor =
  695.             XCreateFontCursor(XtDisplay(topLevel), XC_watch);
  696.  
  697.         /* The window will be as big as the display screen,
  698.            and clipped by its own parent window, so we never
  699.            have to worry about resizing */
  700.  
  701.         waitWindow = 
  702.             XCreateWindow(dpy, XtWindow(topLevel),
  703.                 0, 0,
  704.                 (unsigned int) SERVER_MAX_WINDOW_WIDTH,
  705.                 (unsigned int) SERVER_MAX_WINDOW_HEIGHT,
  706.                 (unsigned int) 0,
  707.                 CopyFromParent, InputOnly, CopyFromParent,
  708.                 valuemask, &attributes);
  709.     }
  710.     if (statType != STAT_USER) {
  711.         XMapWindow(dpy, waitWindow);
  712.         XRaiseWindow(dpy, waitWindow);
  713.     } else {
  714.         XUnmapWindow(dpy, waitWindow);
  715.     }
  716.  
  717.     n=0;
  718.     XtSetArg(args[n], XtNlabel, (String) newLabel);  n++;
  719.     XtSetValues(statusLabel, args, n);
  720.     WaitForAllPendingEventsAndExpose(
  721.             XtDisplay(statusLabel),
  722.             (Window) NULL);
  723. }
  724.  
  725.  
  726. /* changeDirList
  727.    change the directory list contents */
  728.  
  729. void
  730. changeDirList(list)
  731. char    *list[];
  732. {
  733.     if (list == NULL  ||  list[0] == NULL) 
  734.         XawListChange(dirList, emptyList, 0, 0, True);    
  735.     else
  736.         XawListChange(dirList, list, 0, 0, True);    
  737.     
  738.     checkButtonState(BS_previous);
  739. }
  740.  
  741.  
  742. /* changeMarkList
  743.    change the bookmark list contents */
  744.  
  745. void
  746. changeMarkList(list)
  747. char    *list[];
  748. {
  749.     if (list == NULL  ||  list[0] == NULL)
  750.         XawListChange(markList, emptyList, 0, 0, True);    
  751.     else
  752.         XawListChange(markList, list, 0, 0, True);    
  753. }
  754.  
  755.  
  756. /* unselectAllActionProc
  757.    implement the unselectAll action */
  758.  
  759. void
  760. unselectAllActionProc(w, event, params, numParams)
  761. Widget        w[];
  762. XEvent        *event;
  763. String        *params;
  764. Cardinal    *numParams;
  765. {
  766.     unselectAllProc(NULL, NULL, NULL);
  767. }
  768.  
  769.  
  770. /* upActionProc
  771.    implement the up action */
  772.  
  773. void
  774. upActionProc(w, event, params, numParams)
  775. Widget        w[];
  776. XEvent        *event;
  777. String        *params;
  778. Cardinal    *numParams;
  779. {
  780.     if (! atFirstDir()) upProc(upButton, NULL, NULL);
  781. }
  782.  
  783.  
  784. /* quitAppProc
  785.    implement the quit application action */
  786.  
  787. void
  788. quitAppProc(w, event, params, numParams)
  789. Widget        w[];
  790. XEvent        *event;
  791. String        *params;
  792. Cardinal    *numParams;
  793. {
  794.     quitProc(NULL, (XtPointer) (!appResources->swapRestartAndQuit), NULL);
  795. }
  796.  
  797.  
  798. #define N_OTHERS 8
  799. typedef struct {
  800.     char        *name;
  801.     XtCallbackProc    callback;
  802.     XtPointer    clientData;
  803. } otherMenuItemStruct;
  804.  
  805. static otherMenuItemStruct otherItems[] = {
  806.             {"copy", fetchProc, (XtPointer) TRUE},
  807.             {"unmarkAll", unmarkAllProc, NULL},
  808.             {"loadMarks", markLoadProc, NULL},
  809.             {"saveMarks", markSaveProc, NULL},
  810.             {"options", optionsProc, NULL},
  811.             {"oneItem", oneItemProc, NULL},
  812.             {"version", versionProc, NULL},
  813.             {"restart", quitProc, (XtPointer) FALSE}};
  814.  
  815.  
  816.  
  817. /* makeGopherPanel
  818.    create the elements of the main gopher panel */
  819.  
  820. void
  821. makeGopherPanel(top)
  822. Widget    top;
  823. {
  824.     Widget        quitButton, helpButton,
  825.             spacer,
  826.             dirForm, dirView,
  827.             markForm, markView ;
  828.     Widget        statusForm, goBox;
  829.     Widget        otherMenuShell, otherMenuItem[N_OTHERS], otherButton;
  830.  
  831.     int        i;
  832.     Arg        args[10];
  833.     Cardinal    n;
  834.  
  835.     static XtActionsRec    actionsTable[] = {
  836.             {"up",           (XtActionProc) upActionProc},
  837.             {"quitApp",      (XtActionProc) quitAppProc},
  838.             {"unselectAll",  (XtActionProc) unselectAllActionProc}
  839.         };
  840.  
  841.  
  842.     topLevel = top;
  843.  
  844.     XtAppAddActions(appcon, actionsTable, XtNumber(actionsTable));
  845.  
  846.     makeXThings();
  847.  
  848.  
  849.     /* create main gopher panel */
  850.     gopherPanel = XtCreateManagedWidget("gopherPanel", panedWidgetClass,
  851.                     topLevel, NULL, (Cardinal) 0);
  852.         /*
  853.         XtAugmentTranslations(gopherPanel, transTable);
  854.         */
  855.  
  856.     /* create STATUS form */
  857.     statusForm = XtCreateManagedWidget("statusForm", formWidgetClass,
  858.                     gopherPanel, NULL, (Cardinal) 0);
  859.  
  860.  
  861.     /* create DIRECTORY FORM */
  862.     dirForm = XtCreateManagedWidget("directoryForm", formWidgetClass,
  863.                     gopherPanel, NULL, (Cardinal) 0);
  864.  
  865.     /* create GO box */
  866.     goBox = XtCreateManagedWidget("goBox", boxWidgetClass,
  867.                     gopherPanel, NULL, (Cardinal) 0);
  868.  
  869.  
  870.     /* create BOOKMARK FORM */
  871.     markForm = XtCreateManagedWidget("bookmarkForm", formWidgetClass,
  872.                     gopherPanel, NULL, (Cardinal) 0);
  873.  
  874.     /* create QUIT button */
  875.  
  876.         n = 0;
  877.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  878.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  879.         XtSetArg(args[n], XtNleft,    XawChainLeft);  n++;
  880.         XtSetArg(args[n], XtNright,    XawChainLeft);  n++;
  881.     quitButton = XtCreateManagedWidget("quit", commandWidgetClass,
  882.                     statusForm, args, n);
  883.         XtAddCallback(quitButton, XtNcallback,
  884.                 quitProc, (XtPointer) TRUE);
  885.  
  886.  
  887.     /* create OTHER ACTIONS button */
  888.  
  889.         n = 0;
  890.         XtSetArg(args[n], XtNmenuName, "otherActionsMenu");  n++;
  891. #ifndef XGOPHER_X11R4
  892.         XtSetArg(args[n], XtNleftBitmap, pulldownPixmap);  n++;
  893. #endif /* XGOPHER_X11R4 */
  894.         XtSetArg(args[n], XtNfromHoriz,    quitButton);  n++;
  895.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  896.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  897.         XtSetArg(args[n], XtNleft,    XawChainLeft);  n++;
  898.         XtSetArg(args[n], XtNright,    XawChainLeft);  n++;
  899.     otherButton = XtCreateManagedWidget("other", menuButtonWidgetClass,
  900.                     statusForm, args, n);
  901.  
  902.  
  903.         /* create OTHER ACTIONS MENU holder */
  904.  
  905.                 n=0;
  906.         otherMenuShell = XtCreatePopupShell("otherActionsMenu",
  907.                                 simpleMenuWidgetClass,
  908.                 otherButton, args, n);
  909.  
  910.  
  911.         /* create OTHER ACTIONS MENU ENTRIES */
  912.  
  913.     copyButton = NULL;
  914.     saveButton = NULL;
  915.  
  916.         for (i=0; i<N_OTHERS; i++) {
  917.                         n=0;
  918.         /* some items shouldn't be shown in the menu */
  919.  
  920.         if (strcmp(otherItems[i].name, "copy") == 0  &&
  921.             ! appResources->allowCopy) continue;
  922.         if (strcmp(otherItems[i].name, "saveMarks") == 0  &&
  923.             ! appResources->allowBookmarkSave) continue;
  924.         if (strcmp(otherItems[i].name, "oneItem") == 0  &&
  925.             ! appResources->singleItemButton) continue;
  926.         if (strcmp(otherItems[i].name, "options") == 0  &&
  927.             ! appResources->optionsButton) continue;
  928.         if (strcmp(otherItems[i].name, "restart") == 0  &&
  929.             ! appResources->restartButton) continue;
  930.  
  931.                 otherMenuItem[i] = XtCreateManagedWidget(otherItems[i].name,
  932.                                         smeBSBObjectClass,
  933.                                         otherMenuShell, args, n);
  934.                         XtAddCallback(otherMenuItem[i], XtNcallback,
  935.                         otherItems[i].callback,
  936.                         otherItems[i].clientData);
  937.  
  938.         /* save pointers to some items so they can be turned on/off */
  939.  
  940.         if (strcmp(otherItems[i].name, "copy") == 0)
  941.             copyButton = otherMenuItem[i];
  942.         if (strcmp(otherItems[i].name, "saveMarks") == 0)
  943.             saveButton = otherMenuItem[i];
  944.         if (strcmp(otherItems[i].name, "loadMarks") == 0)
  945.             loadButton = otherMenuItem[i];
  946.         if (strcmp(otherItems[i].name, "unmarkAll") == 0)
  947.             unmarkAllButton = otherMenuItem[i];
  948.         }
  949.             
  950.  
  951.     /* create HELP button */
  952.  
  953.         n = 0;
  954.         XtSetArg(args[n], XtNfromHoriz,    otherButton);  n++;
  955.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  956.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  957.         XtSetArg(args[n], XtNleft,    XawChainLeft);  n++;
  958.         XtSetArg(args[n], XtNright,    XawChainLeft);  n++;
  959.     helpButton = XtCreateManagedWidget("help", commandWidgetClass,
  960.                     statusForm, args, n);
  961.         XtAddCallback(helpButton, XtNcallback, helpProc, NULL);
  962.  
  963.  
  964.     /* create STATUS label */
  965.  
  966.         n=0;
  967.         XtSetArg(args[n], XtNfromVert,    quitButton);  n++;
  968.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  969.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  970.         XtSetArg(args[n], XtNleft,    XawChainLeft);  n++;
  971.         XtSetArg(args[n], XtNright,    XawChainRight);  n++;
  972.     statusLabel = XtCreateManagedWidget("status", labelWidgetClass,
  973.                     statusForm, args, n);
  974.  
  975.  
  976.     /* create GOTO button */
  977.  
  978.     fetchButton = XtCreateManagedWidget("fetch", commandWidgetClass,
  979.                     goBox, NULL, (Cardinal) 0);
  980.         XtAddCallback(fetchButton, XtNcallback,
  981.                         fetchProc, (XtPointer)TRUE);
  982.  
  983.     /* create INFO button */
  984.  
  985.     infoButton = XtCreateManagedWidget("info", commandWidgetClass,
  986.                     goBox, NULL, (Cardinal) 0);
  987.         XtAddCallback(infoButton, XtNcallback, infoProc,NULL);
  988.  
  989.         {
  990.              String temp;
  991.              XtSetArg(args[0], XtNlabel, &temp);
  992.              XtGetValues(infoButton, args, 1);
  993.              infoItemLabel = XtMalloc(sizeof(char) * strlen(temp) + 1);
  994.              strcpy(infoItemLabel, temp);
  995.             }
  996.         
  997.         infoItemLabelArg.value  = (XtArgVal) infoItemLabel;
  998.         infoDirLabelArg.value   = (XtArgVal) infoDirLabel;
  999.  
  1000.  
  1001.     /* create UP button */
  1002.  
  1003.     upButton = XtCreateManagedWidget("up", commandWidgetClass,
  1004.                     goBox, NULL, (Cardinal) 0);
  1005.         XtAddCallback(upButton, XtNcallback, upProc, NULL);
  1006.  
  1007.  
  1008.     /* create some space */
  1009.  
  1010.     spacer = XtCreateManagedWidget("spacer", simpleWidgetClass,
  1011.                     goBox, NULL, (Cardinal) 0);
  1012.  
  1013.     /* create MARK button */
  1014.  
  1015.     markButton = XtCreateManagedWidget("mark", commandWidgetClass,
  1016.                     goBox, NULL, (Cardinal) 0);
  1017.         XtAddCallback(markButton, XtNcallback, markProc, NULL);
  1018.         
  1019.         {
  1020.              String temp;
  1021.              XtSetArg(args[0], XtNlabel, &temp);
  1022.              XtGetValues(markButton, args, 1);
  1023.              markItemLabel = XtMalloc(sizeof(char) * strlen(temp) + 1);
  1024.              strcpy(markItemLabel, temp);
  1025.             }
  1026.         
  1027.         markItemLabelArg.value  = (XtArgVal) markItemLabel;
  1028.         markDirLabelArg.value   = (XtArgVal) markDirLabel;
  1029.  
  1030.     /* create UNMARK button */
  1031.  
  1032.     unmarkButton = XtCreateManagedWidget("unmark", commandWidgetClass,
  1033.                     goBox, NULL, (Cardinal) 0);
  1034.         XtAddCallback(unmarkButton, XtNcallback, unmarkProc, NULL);
  1035.  
  1036.  
  1037.  
  1038.     /* ============ DIRECTORY PANEL =========== */
  1039.  
  1040.     /* the directory panel will have this heirarchy:
  1041.           directoryForm
  1042.          directoryTitle
  1043.          directoryView
  1044.              directory
  1045.              (scrollbar: automatic)
  1046.     */
  1047.  
  1048.     /* create DIRECTORY TITLE label */
  1049.  
  1050.         n=0;
  1051.         /*
  1052.         XtSetArg(args[n], XtNborderWidth, 0);  n++;
  1053.         */
  1054.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  1055.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  1056.  
  1057.     dirLabel = XtCreateManagedWidget("directoryTitle", labelWidgetClass,
  1058.                     dirForm, args, n);
  1059.  
  1060.     /* create DIRECTORY VIEWPORT */
  1061.  
  1062.         n = 0;
  1063.         XtSetArg(args[n], XtNfromVert, dirLabel);  n++;
  1064.         XtSetArg(args[n], XtNallowVert, True);  n++;
  1065.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  1066.         XtSetArg(args[n], XtNbottom,    XawChainBottom);  n++;
  1067.     dirView = XtCreateManagedWidget("directoryView", viewportWidgetClass,
  1068.                     dirForm, args, n);
  1069.  
  1070.     /* create CURRENT DIRECTORY LIST display */
  1071.  
  1072.         n = 0;
  1073.         XtSetArg(args[n], XtNforceColumns, True);  n++;
  1074.         XtSetArg(args[n], XtNdefaultColumns, 1);  n++;
  1075.         XtSetArg(args[n], XtNlist, emptyList);  n++;
  1076.         XtSetArg(args[n], XtNhorizDistance, 0);  n++;
  1077.     dirList = XtCreateManagedWidget("directory", listWidgetClass,
  1078.                     dirView, args, n);
  1079.         XtAddCallback(dirList, XtNcallback, dirSelectProc,NULL);
  1080.  
  1081.     /* ============ BOOKMARK PANEL =========== */
  1082.  
  1083.     /* the bookmark panel will have this heirarchy:
  1084.           bookmarkForm
  1085.          bookmarkTitle
  1086.          bookmarkView
  1087.              bookmark
  1088.              (scrollbar: automatic)
  1089.     */
  1090.  
  1091.     /* create BOOKMARK TITLE label */
  1092.  
  1093.         n=0;
  1094.         /*
  1095.         XtSetArg(args[n], XtNborderWidth, 0);  n++;
  1096.         */
  1097.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  1098.         XtSetArg(args[n], XtNbottom,    XawChainTop);  n++;
  1099.     markLabel = XtCreateManagedWidget("bookmarkTitle", labelWidgetClass,
  1100.                     markForm, args, n);
  1101.  
  1102.     /* create BOOKMARK VIEWPORT */
  1103.  
  1104.         n=0;
  1105.         XtSetArg(args[n], XtNfromVert, markLabel);  n++;
  1106.         XtSetArg(args[n], XtNallowVert, True);  n++;
  1107.         XtSetArg(args[n], XtNtop,    XawChainTop);  n++;
  1108.         XtSetArg(args[n], XtNbottom,    XawChainBottom);  n++;
  1109.     markView = XtCreateManagedWidget("bookmarkView", viewportWidgetClass,
  1110.                     markForm, args, n);
  1111.  
  1112.     /* create BOOKMARK LIST display */
  1113.  
  1114.         n = 0;
  1115.         XtSetArg(args[n], XtNforceColumns, True);  n++;
  1116.         XtSetArg(args[n], XtNdefaultColumns, 1);  n++;
  1117.         XtSetArg(args[n], XtNlist, emptyList);  n++;
  1118.         XtSetArg(args[n], XtNhorizDistance, 0);  n++;
  1119.     markList = XtCreateManagedWidget("bookmark", listWidgetClass,
  1120.                     markView, args, n);
  1121.         XtAddCallback(markList, XtNcallback, markSelectProc,NULL);
  1122.  
  1123.     checkButtonState(BS_all);
  1124.  
  1125.         /* for ICCCM window manager protocol complience */
  1126.  
  1127.         XtOverrideTranslations (topLevel,
  1128.             XtParseTranslationTable ("<Message>WM_PROTOCOLS: quitApp()"));
  1129.         XtRealizeWidget(topLevel);
  1130.         (void) XSetWMProtocols (XtDisplay(topLevel), XtWindow(topLevel),
  1131.                                     &wmDeleteAtom, 1);
  1132.  
  1133.  
  1134.     return;
  1135. }
  1136.  
  1137.